<template>
  <el-form
    v-bind="$attrs"
    :label-width="props.inline ? '80px' : props.labelWidth"
    :model="_formData"
    :rules="formRules"
    :inline="inline"
    :ref="(ref: FormInstance) => initializeInstance(ref)"
  >
    <ElRow :gutter="24">
      <template
        v-for="field in (showFields || props.fields).slice(
          0,
          props.inline && props.showExpand && conditionFold
            ? props.spliceLength
            : _formData.length
        )"
        :key="field.key"
      >
        <ElCol v-bind="setFieldKeyCol(field, props)">
          <el-form-item
            :label="(field.label || field.key) + ':'"
            :prop="field.key"
            v-bind="{ ...field.formItemAttributes }"
          >
            <component
              v-if="!field.slot"
              :is="field.tag"
              v-model="_formData[field.key]"
              :placeholder="
                field.attrs && field.attrs.placeholder
                  ? field.attrs.placeholder
                  : field.label
              "
              v-bind="{
                ...field?.attrs,
                disabled: props.isView || field?.attrs?.disabled
              }"
              style="width: 100%"
              v-on="field.on"
            />

            <slot
              v-else
              :name="field.key"
              :value="_formData[field.key]"
              :field="field"
            />
          </el-form-item>
        </ElCol>
      </template>
      <template v-if="inline">
        <div class="buttons">
          <el-button type="primary" @click="search" :icon="Search"
            >搜索</el-button
          >
          <el-button @click="reset" :icon="Refresh">重置</el-button>
          <el-button
            type="primary"
            link
            @click="areConditionFold"
            v-if="props.showExpand"
          >
            {{ conditionFold ? '展开' : '收起' }}
            <el-icon v-if="conditionFold"><ArrowDown /></el-icon>
            <el-icon v-else><ArrowUp /></el-icon>
          </el-button>
        </div>
      </template>
    </ElRow>
  </el-form>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'

import type { FormInstance } from 'element-plus'

import { ArrowDown, ArrowUp, Search, Refresh } from '@element-plus/icons-vue'

import defaultProps, {
  useFormRules,
  defaultEmits,
  setFieldKeyCol
} from './props'
import { cloneDeep } from 'lodash-es'

import { useFormMethods, useFormFields, useFormData } from './hooks'

const {
  initializeInstance,
  getFormInstance,
  validate,
  resetForm,
  clearValidate
} = useFormMethods()

const props = defineProps(defaultProps)
const emits = defineEmits(defaultEmits)

const { showFields } = useFormFields(props)

const { _formData } = useFormData(showFields, props)

const formRules = computed(() => useFormRules(showFields.value || []))

const conditionFold = ref(true)

const areConditionFold = () => {
  conditionFold.value = !conditionFold.value
}

const search = () => {
  const searchValue = cloneDeep(_formData.value)

  emits('search', searchValue)
}

const reset = () => {
  let data: Record<string, string | undefined> = {}
  Object.keys(_formData.value).forEach((key) => {
    data[key] = undefined
  })
  emits('search', data)
  resetForm()
}

const getFormValue = async () => {
  const valid = await validate()
  if (!valid) return console.error('校验未通过')
  return new Promise((resolve) => {
    resolve(cloneDeep(_formData.value))
  })
}

defineExpose({
  getFormInstance,
  validate: () => getFormValue(),
  resetForm,
  clearValidate
})

defineOptions({
  name: 'CEForm'
})
</script>

<style scoped lang="scss">
.el-form {
  padding: 20px;
  .el-form-item {
    width: 100%;
  }
}
.buttons {
  display: inline-block;
  margin-left: 20px;
}
</style>
